import { AnyObj, ObserveTyp } from './types'
import { getValue } from './utils'
import Dep from "./Deps"

//将对象包装成getter setter
export default class Observer implements ObserveTyp {
    data: AnyObj
    constructor(data: AnyObj) {
        this.data = data
        this.walk(this.data)
    }
    walk(data: AnyObj) {
        if (data && typeof data === 'object') {
            Object.keys(data).forEach(key => {
                this._defineReactive(data, key)
            })
        }
    }
    _defineReactive(obj: AnyObj, key: string) {
        let value = getValue(obj, key)
        let deps = new Dep()
        this.walk(value)
        let that = this;

        Object.defineProperty(obj, key, {
            configurable: true,
            enumerable: true,
            get() {
                Dep.target && deps.addWatcher(Dep.target)
                return value
            },
            set(nval) {
                if (nval === value){
                    return
                }
                that.walk(nval)
                value = nval
                deps.notify()
            }
        })
    }

}